#include "protocols/POP3.h"
#include "utilities/ReadablePacket.h"
#include "protocols/ProtocalCode.h"
#include "protocols/ProtocalPool.h"
#include "protocols/ShowableItem.h"
#include "utilities/utilities.h"

REGISTER_PROTOCOL(POP3Protocal)

int POP3Header::spaceIndex() const
{
	QByteArray data = QByteArray::fromRawData((const char *)mData, getHeaderLength() - 2);
	return data.indexOf(" ");
}

POP3Header::_mType POP3Header::typeFlag() const
{
	if (spaceIndex() > 0)
	{
		QString& data = byteToString((const char *)mData, " ");

		if ("+OK" == data)
		{
			return RESPONSE;
		}else
		{
			return REQUEST;
		}
	}else{
		return DATA;
	}
}

void POP3Header::toShowableItems(ShowableItem* root) const
{
	int pos = mPos;
	ShowableItem* tmp,* flags;

	ShowableItem* protocal = createProtocalItem("Post Office Protocol (POP3)", pos, getHeaderLength());
	root->pushChild(protocal);
	
	if (DATA != typeFlag())
	{
		tmp = createItemUnchange(qPrintable(byteToString((const char *)mData, "\r\n")), "", "", pos, getHeaderLength());
		protocal->pushChild(tmp);

		if (RESPONSE == typeFlag())
		{
			QString& data =  byteToString((const char *)mData, " ");
			flags = createItem("Response code: ",data, pos, spaceIndex());
			tmp->pushChild(flags);

			QString& ndata = byteToString((const char *)(mData + spaceIndex() + 1), "\r\n");
			flags = createItem("Response arg: ", ndata, ++pos, ndata.size());
			tmp->pushChild(flags);

			if (ndata.size() != (getHeaderLength() - spaceIndex() - 3))
			{
				tmp = createItem(qPrintable(QString("Data ( %1 bytes )").arg(getHeaderLength() - spaceIndex() - 1)), "", pos, getHeaderLength() - spaceIndex() - 1);
				protocal->pushChild(tmp);
			}
		}else{		
			flags = createItem("Request command: ",byteToString((const char *)mData, " "), pos, spaceIndex());
			tmp->pushChild(flags);

			flags = createItem("Request arg: ", byteToString((const char *)(mData + spaceIndex() + 1), "\r\n"), ++pos, getHeaderLength() - spaceIndex() - 3);
			tmp->pushChild(flags);
		}
	}else{
		tmp = createItem(qPrintable(QString("Data ( %1 bytes)").arg(getHeaderLength())), "", pos, getHeaderLength());
		protocal->pushChild(tmp);
	}
}

POP3Protocal::POP3Protocal() : Protocol(POP3,QString("POP3"))
{
	shared_ptr<AppProtocolProperty> prop = make_shared<AppProtocolProperty>();
	prop->mDefaultPort.push_back(110);
	mInfo = prop;
}

boost::shared_ptr<PacketHeader> 
POP3Protocal::analyzeProc(boost::shared_ptr<ReadablePacket> packet,int low,int high,boost::shared_ptr<Protocol>& tip)
{
	boost::shared_ptr<POP3Header> header(make_shared<POP3Header>(POP3Protocal_register.m_Instance,packet->getData(),low,high - low + 1));

	tip.reset();

	return header;
}